package com.soft.bams.client;

import com.soft.bams.entity.*;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;


public class BusinessPanel extends JPanel {
    private ATMClient atmClient;
    private Account currentAccount;
    private Timer refreshTimer;

    private JLabel accountLabel = new JLabel("账号:");
    private JLabel nameLabel = new JLabel("姓名:");
    private JLabel balanceLabel = new JLabel("余额:");
    private JLabel creditLabel = new JLabel("信用额度:");
    private JLabel loanLabel = new JLabel("贷款金额:");

    private JLabel accountValue = new JLabel();
    private JLabel nameValue = new JLabel();
    private JLabel balanceValue = new JLabel();
    private JLabel creditValue = new JLabel();
    private JLabel loanValue = new JLabel();

    private JComboBox<String> operation;
    private JTextField amountField = new JTextField();
    private JButton submitBtn = new JButton("提交");
    private JButton backBtn = new JButton("返回");

    private JTextField targetAccountField = new JTextField();
    private JLabel targetAccountLabel = new JLabel("转入账号:");

    public BusinessPanel(ATMClient atmClient) {
        this.atmClient = atmClient;
        setLayout(null);
        initComponents();
        initRefreshTimer();
    }

    private void initRefreshTimer() {
        refreshTimer = new Timer(1000, e -> refreshBalance());
        refreshTimer.setRepeats(true);

        this.addComponentListener(new ComponentAdapter() {
            @Override
            public void componentShown(ComponentEvent e) {
                refreshTimer.start();
            }

            @Override
            public void componentHidden(ComponentEvent e) {
                refreshTimer.stop();
            }
        });
    }

    private void refreshBalance() {
        if (currentAccount != null) {
            Object response = atmClient.sendCommand("getAccount#" + currentAccount.getId());
            if (response instanceof Account) {
                currentAccount = (Account) response;
                updateDisplay();
            }
        }
    }

    private void initComponents() {
        // 信息显示标签
        accountLabel.setBounds(50, 30, 80, 25);
        accountValue.setBounds(140, 30, 200, 25);

        nameLabel.setBounds(50, 70, 80, 25);
        nameValue.setBounds(140, 70, 200, 25);

        balanceLabel.setBounds(50, 110, 80, 25);
        balanceValue.setBounds(140, 110, 200, 25);

        creditLabel.setBounds(50, 150, 80, 25);
        creditValue.setBounds(140, 150, 200, 25);
        creditLabel.setVisible(false);
        creditValue.setVisible(false);

        loanLabel.setBounds(50, 190, 80, 25);
        loanValue.setBounds(140, 190, 200, 25);
        loanLabel.setVisible(false);
        loanValue.setVisible(false);

        targetAccountLabel.setBounds(50, 310, 80, 25);
        targetAccountField.setBounds(140, 310, 200, 25);
        targetAccountLabel.setVisible(false);
        targetAccountField.setVisible(false);
        add(targetAccountLabel);
        add(targetAccountField);

        // 操作选择
        JLabel operationLabel = new JLabel("选择操作:");
        operationLabel.setBounds(50, 230, 80, 25);

        operation = new JComboBox<>(new String[]{"存款", "取款", "转账"});
        operation.setBounds(140, 230, 200, 25);

        JLabel amountLabel = new JLabel("金额:");
        amountLabel.setBounds(50, 270, 80, 25);
        amountField.setBounds(140, 270, 200, 25);

        submitBtn.setBounds(140, 350, 100, 30);
        backBtn.setBounds(260, 350, 100, 30);

        // 添加组件
        add(accountLabel);
        add(accountValue);
        add(nameLabel);
        add(nameValue);
        add(balanceLabel);
        add(balanceValue);
        add(creditLabel);
        add(creditValue);
        add(loanLabel);
        add(loanValue);
        add(operationLabel);
        add(operation);
        add(amountLabel);
        add(amountField);
        add(submitBtn);
        add(backBtn);

        // 事件处理
        submitBtn.addActionListener(this::handleOperation);
        backBtn.addActionListener(e -> {
            atmClient.showPanel("Main");
            Object response = atmClient.sendCommand("removeIdFromIdIpMap#" + currentAccount.getId());
            JOptionPane.showMessageDialog(this,response);
        });

        operation.addActionListener(e -> {
            String selected = (String) operation.getSelectedItem();
            targetAccountLabel.setVisible("转账".equals(selected));
            targetAccountField.setVisible("转账".equals(selected));
        });
    }

    public void setAccount(Account account) {
        this.currentAccount = account;
        updateDisplay();
        updateOperation();
    }

    public Account getCurrentAccount() {
        return currentAccount;
    }

    private void updateDisplay() {
        accountValue.setText(String.valueOf(currentAccount.getId()));
        nameValue.setText(currentAccount.getName());
        balanceValue.setText(String.valueOf(currentAccount.getBalance()));

        if (currentAccount instanceof CreditAccount) {
            creditLabel.setVisible(true);
            creditValue.setVisible(true);
            creditValue.setText(String.valueOf(((CreditAccount) currentAccount).getCeiling()));
        } else {
            creditLabel.setVisible(false);
            creditValue.setVisible(false);
        }

        if (currentAccount instanceof LoanSavingAccount) {
            loanLabel.setVisible(true);
            loanValue.setVisible(true);
            loanValue.setText(String.valueOf(((LoanSavingAccount) currentAccount).getLoanAmount()));
        } else if (currentAccount instanceof LoanCreditAccount) {
            loanLabel.setVisible(true);
            loanValue.setVisible(true);
            loanValue.setText(String.valueOf(((LoanCreditAccount) currentAccount).getLoanAmount()));
        } else {
            loanLabel.setVisible(false);
            loanValue.setVisible(false);
        }
    }

    private void updateOperation() {
        DefaultComboBoxModel<String> model = new DefaultComboBoxModel<>();
        model.addElement("存款");
        model.addElement("取款");
        model.addElement("转账");

        if (currentAccount instanceof CreditAccount) {
            model.addElement("修改透支额度");
        }

        if (currentAccount instanceof Loanable) {
            model.addElement("贷款");
            model.addElement("还贷款");
        }

        operation.setModel(model);
    }

    private void handleOperation(ActionEvent e) {
        try {
            String operation = (String) this.operation.getSelectedItem();
            double amount = Double.parseDouble(amountField.getText());

            Object response = null;
            String command = "";

            switch (operation) {
                case "存款":
                    command = "deposit#" + currentAccount.getId() + "#" + amount;
                    response = atmClient.sendCommand(command);
                    break;

                case "取款":
                    String password = JOptionPane.showInputDialog(this, "请输入密码确认取款:");
                    if (password == null || password.isEmpty()) return;
                    command = "withdraw#" + currentAccount.getId() + "#" + password + "#" + amount;
                    response = atmClient.sendCommand(command);
                    break;

                case "转账":
                    handleTransfer(amount);
                    return;

                case "修改透支额度":
                    String pwd = JOptionPane.showInputDialog(this, "请输入密码确认修改:");
                    if (pwd == null || pwd.isEmpty()) return;
                    command = "updateCeiling#" + currentAccount.getId() + "#" + pwd + "#" + amount;
                    response = atmClient.sendCommand(command);
                    break;

                case "贷款":
                    command = "requestLoan#" + currentAccount.getId() + "#" + amount;
                    response = atmClient.sendCommand(command);
                    break;

                case "还贷款":
                    command = "payLoan#" + currentAccount.getId() + "#" + amount;
                    response = atmClient.sendCommand(command);
                    break;

                default:
                    JOptionPane.showMessageDialog(this, "暂不支持此操作", "提示", JOptionPane.INFORMATION_MESSAGE);
                    return;
            }

            handleResponse(response);

        } catch (NumberFormatException ex) {
            JOptionPane.showMessageDialog(this, "金额格式错误", "错误", JOptionPane.ERROR_MESSAGE);
        }
    }

    private void handleTransfer(double amount) {
        if (targetAccountField.getText().isEmpty()) {
            JOptionPane.showMessageDialog(this, "请输入转入账号", "错误", JOptionPane.ERROR_MESSAGE);
            return;
        }

        try {
            long targetAccountId = Long.parseLong(targetAccountField.getText());
            if (targetAccountId == currentAccount.getId()) {
                JOptionPane.showMessageDialog(this, "不能向自己转账", "错误", JOptionPane.ERROR_MESSAGE);
                return;
            }

            String password = JOptionPane.showInputDialog(this, "请输入密码确认转账:");
            if (password == null || password.isEmpty()) return;

            String command = "transfer#" + currentAccount.getId() + "#" + password + "#" +
                    targetAccountId + "#" + amount;
            Object response = atmClient.sendCommand(command);

            handleResponse(response);

        } catch (NumberFormatException ex) {
            JOptionPane.showMessageDialog(this, "转入账号格式错误", "错误", JOptionPane.ERROR_MESSAGE);
        }
    }

    private void handleResponse(Object response) {
        if (response instanceof Account) {
            currentAccount = (Account) response;
            updateDisplay();
            amountField.setText("");
            targetAccountField.setText("");
            targetAccountField.setVisible(false);
            targetAccountLabel.setVisible(false);
            JOptionPane.showMessageDialog(this, "操作成功", "提示", JOptionPane.INFORMATION_MESSAGE);
        } else if (response instanceof String) {
            JOptionPane.showMessageDialog(this, response, "错误", JOptionPane.ERROR_MESSAGE);
        }
    }
}

